﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;

namespace SimpleFMMatrix.ViewModel
{
    public class PlayByKeyboardBehavior : Behavior<Window>
    {
        public static readonly DependencyProperty MatrixVMProperty =
            DependencyProperty.Register("MatrixVM", typeof(FMMatrixVM), typeof(PlayByKeyboardBehavior),
            new PropertyMetadata(null));

        public FMMatrixVM MatrixVM
        {
            get { return (FMMatrixVM)GetValue(MatrixVMProperty); }
            set { SetValue(MatrixVMProperty, value); }
        }

        private int MapKeyboard(Key key)
        {
            switch (key)
            {
                case Key.Z: return 48;
                case Key.S: return 49;
                case Key.X: return 50;
                case Key.D: return 51;
                case Key.C: return 52;
                case Key.V: return 53;
                case Key.G: return 54;
                case Key.B: return 55;
                case Key.H: return 56;
                case Key.N: return 57;
                case Key.J: return 58;
                case Key.M: return 59;
                case Key.OemComma: return 60;
                case Key.L: return 61;
                case Key.OemPeriod: return 62;
                case Key.OemSemicolon: return 63;
                case Key.OemQuestion: return 64;
                case Key.Q: return 60;
                case Key.D2: return 61;
                case Key.W: return 62;
                case Key.D3: return 63;
                case Key.E: return 64;
                case Key.R: return 65;
                case Key.D5: return 66;
                case Key.T: return 67;
                case Key.D6: return 68;
                case Key.Y: return 69;
                case Key.D7: return 70;
                case Key.U: return 71;
                case Key.I: return 72;
                case Key.D9: return 73;
                case Key.O: return 74;
                case Key.D0: return 75;
                case Key.P: return 76;
                case Key.OemOpenBrackets: return 77;
                case Key.OemPlus: return 78;
                case Key.OemCloseBrackets: return 79;
                default: return -1;
            }
        }

        private int KeyToMidiNumber(Key key)
        {
            var result = MapKeyboard(key);
            if ((Keyboard.Modifiers & ModifierKeys.Shift) != 0 & result != -1)
                result += 24;
            return result;
        }

        protected override void OnAttached()
        {
            base.OnAttached();

            AssociatedObject.KeyDown += (s, e) =>
            {
                var midikey = KeyToMidiNumber(e.Key);
                if (midikey < 0) return;
                MatrixVM.PianoKeys[midikey - 21].IsPressed = true;
            };

            AssociatedObject.KeyUp += (s, e) =>
            {
                var midikey = KeyToMidiNumber(e.Key);
                if (midikey < 0) return;
                MatrixVM.PianoKeys[midikey - 21].IsPressed = false;
            };
        }
    }
}
